#include "SoftwareUart.h"


SoftwareUart::SoftwareUart()
{
	config.dataSize = 7;
	config.stopNumber = SoftwareUart::OneStop;
	config.polarity = SoftwareUart::High;
	config.parity = SoftwareUart::NoParity;
	config.io = SoftwareUart::Input;
	config.finished = 0;
	bit = BitPointer();
	shifter = Shifter(10, bit, config.io, config.io);
}
SoftwareUart::SoftwareUart(SoftwareUart::UartConfig c, BitPointer& b)
{
	config = c;
	bit = b;
	unsigned int total = 1;
	if(config.parity != SoftwareUart::NoParity)
		total++;
	total = total + 1 + config.dataSize;
	total = total + 1 + config.stopNumber;
	bit = b;
	shifter = Shifter(total, bit, config.io, config.io);
}

void SoftwareUart::set(unsigned char data)
{	//this takes care of packing data into a usable format
	unsigned char total = 1;
	total = total + 1 + 1 + config.dataSize;
	total = total + 1 + config.stopNumber;
	if(config.parity != SoftwareUart::NoParity)
		total++; //add parity bit to the total.
	BitArray array = BitArray(total);
	if(config.polarity == SoftwareUart::High)
		array[0].setBit(0);
	else
		array[0].setBit(1);
	unsigned char i = 0;
	for(i = 0; i < config.dataSize+1; i++)
		array[i+1].setBit(GetBit(data, i));
	unsigned char currentCount = i;
	i = 0;
	//check if you are doing parity now
	if(config.parity != SoftwareUart::NoParity)
	{
		unsigned char p = calculateParity(config.parity, data);
		array[currentCount].setBit(p);
		currentCount++;
	}

	for(i = 0; i < config.stopNumber+1; i++)
		array[currentCount+i].setBit(config.polarity);
	//the array has been set now hurray. now put in the shifter.
	shifter.set(array);
}

unsigned char SoftwareUart::get(bool& parityCompare)
{//takes care of processing that data.
	unsigned char total = 1;
	total = total + 1 + 1 + config.dataSize;
	total = total + 1 + config.stopNumber;
	if(config.parity != SoftwareUart::NoParity)
		total++; //add parity bit to the total.
	BitArray array = shifter.get();
	if(config.polarity == SoftwareUart::High)
		array[0].getBit();
	else
		array[0].getBit();
	unsigned char data = 0;

	unsigned char i = 0;
	for(i = 0; i < config.dataSize+1; i++)
		data = SetBit(data, i, array[i+1].getBit());
	unsigned char currentCount = i;
	i = 0;
	unsigned char par = 0;
	parityCompare = true;//means that parity is correct
	//check if you are doing parity now
	if(config.parity != SoftwareUart::NoParity)
	{
		unsigned char p = calculateParity(config.parity, data);
		par = array[currentCount].getBit();
		currentCount++;
		if(p != par)
			parityCompare = false;
		else
			parityCompare = true;
	}

	for(i = 0; i < config.stopNumber+1; i++)
		array[currentCount+i].getBit();
	//the array has been set now hurray. now put in the shifter.
	//shifter.set(array);
	return data;
}


unsigned char SoftwareUart::calculateParity(unsigned char parityChoice, unsigned char data)
{
	unsigned char count = 0;
	unsigned i = 0;
	for(i = 0; i < 8; i++)
		if(GetBit(data, i)==1)
			count++;
	unsigned char even = 0;
	unsigned char odd = 0;
	if(parityChoice == 1) //parity is odd so odd = 1 and even = 0
	{
		even = 0;
		odd = 1;
	}
	else if(parityChoice == 2) //parity is even so even = 1 and odd = 0
	{
		even = 1;
		odd = 0;
	}
	if(count % 2 == 0) //value is even hurray.
		return even;
	else 
		return odd;
}


void SoftwareUart::run()
{

	shifter.shift();
	config.finished = shifter.getFinished();

}

bool SoftwareUart::getFinished()
{
	return config.finished;
}



